From 7859f8ee91b8287d0f0485351d557886ae6fc0bb Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 17 Jan 2016 21:16:33 -0500 Subject: [PATCH] checkbutton: Use a box gadget Now that builtin icons have a baseline, we can just use a box gadget with baseline alignment for the indicator and the label. --- gtk/gtkcheckbutton.c | 287 +++++-------------------------------------- 1 file changed, 34 insertions(+), 253 deletions(-) diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c index c81015bd1e..6395811af9 100644 --- a/gtk/gtkcheckbutton.c +++ b/gtk/gtkcheckbutton.c @@ -35,7 +35,7 @@ #include "gtkwidgetprivate.h" #include "gtkbuiltiniconprivate.h" #include "gtkcssnodeprivate.h" -#include "gtkcsscustomgadgetprivate.h" +#include "gtkboxgadgetprivate.h" #include "gtkcontainerprivate.h" #include "gtkstylecontextprivate.h" #include "gtkcssnumbervalueprivate.h" @@ -106,29 +106,6 @@ static void gtk_check_button_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static gboolean gtk_check_button_draw (GtkWidget *widget, cairo_t *cr); -static void gtk_check_button_draw_indicator (GtkCheckButton *check_button, - cairo_t *cr); - -static void gtk_check_button_measure (GtkCssGadget *gadget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline, - gpointer unused); -static void gtk_check_button_allocate (GtkCssGadget *gadget, - const GtkAllocation *allocation, - int baseline, - GtkAllocation *out_clip, - gpointer unused); -static gboolean gtk_check_button_render (GtkCssGadget *gadget, - cairo_t *cr, - int x, - int y, - int width, - int height, - gpointer data); typedef struct { GtkCssGadget *gadget; @@ -206,11 +183,34 @@ gtk_check_button_finalize (GObject *object) G_OBJECT_CLASS (gtk_check_button_parent_class)->finalize (object); } +static void +gtk_check_button_add (GtkContainer *container, + GtkWidget *widget) +{ + GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container)); + + GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->add (container, widget); + + gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 1, widget); +} + +static void +gtk_check_button_remove (GtkContainer *container, + GtkWidget *widget) +{ + GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container)); + + gtk_box_gadget_remove_widget (GTK_BOX_GADGET (priv->gadget), widget); + + GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->remove (container, widget); +} + static void gtk_check_button_class_init (GtkCheckButtonClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class); object_class->finalize = gtk_check_button_finalize; @@ -224,6 +224,9 @@ gtk_check_button_class_init (GtkCheckButtonClass *class) widget_class->state_flags_changed = gtk_check_button_state_flags_changed; widget_class->direction_changed = gtk_check_button_direction_changed; + container_class->add = gtk_check_button_add; + container_class->remove = gtk_check_button_remove; + /** * GtkCheckButton:indicator-size: * @@ -321,19 +324,14 @@ gtk_check_button_init (GtkCheckButton *check_button) gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (check_button)), "toggle"); widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button)); - priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node, - GTK_WIDGET (check_button), - gtk_check_button_measure, - gtk_check_button_allocate, - gtk_check_button_render, - NULL, - NULL); - + priv->gadget = gtk_box_gadget_new_for_node (widget_node, GTK_WIDGET (check_button)); + gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL); priv->indicator_gadget = gtk_builtin_icon_new ("check", GTK_WIDGET (check_button), priv->gadget, NULL); gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size"); + gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->indicator_gadget, FALSE, FALSE, GTK_ALIGN_BASELINE); gtk_check_button_update_node_state (GTK_WIDGET (check_button)); } @@ -386,145 +384,6 @@ gtk_check_button_new_with_mnemonic (const gchar *label) NULL); } -static gboolean -gtk_check_button_render (GtkCssGadget *gadget, - cairo_t *cr, - int x, - int y, - int width, - int height, - gpointer data) -{ - GtkWidget *widget; - GtkWidget *child; - - widget = gtk_css_gadget_get_owner (gadget); - - gtk_check_button_draw_indicator (GTK_CHECK_BUTTON (widget), cr); - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child) - gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr); - - if (gtk_widget_has_visible_focus (widget)) - { - GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget)); - GtkStyleContext *context; - GtkAllocation allocation; - - gtk_widget_get_allocation (widget, &allocation); - context = gtk_widget_get_style_context (widget); - - if (child && gtk_widget_get_visible (child)) - { - GtkAllocation child_allocation; - - gtk_widget_get_allocation (child, &child_allocation); - gtk_render_focus (context, cr, - child_allocation.x - allocation.x, - child_allocation.y - allocation.y, - child_allocation.width, - child_allocation.height); - } - else - gtk_render_focus (context, cr, x, y, width, height); - } - - return FALSE; -} - -static void -gtk_check_button_measure (GtkCssGadget *gadget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline, - gpointer unused) -{ - GtkWidget *widget; - GtkCheckButtonPrivate *priv; - - widget = gtk_css_gadget_get_owner (gadget); - priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget)); - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - { - GtkWidget *child; - gint check_min, check_nat; - - gtk_css_gadget_get_preferred_size (priv->indicator_gadget, - GTK_ORIENTATION_HORIZONTAL, - for_size, - &check_min, &check_nat, - NULL, NULL); - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - - _gtk_widget_get_preferred_size_for_size (child, - GTK_ORIENTATION_HORIZONTAL, - for_size, - &child_min, &child_nat, - NULL, NULL); - *minimum = check_min + child_min; - *natural = check_nat + child_nat; - } - else - { - *minimum = check_min; - *natural = check_nat; - } - } - else - { - GtkWidget *child; - gint check_min, check_nat; - gint check_min_width, check_nat_width; - - gtk_css_gadget_get_preferred_size (priv->indicator_gadget, - GTK_ORIENTATION_HORIZONTAL, - -1, - &check_min_width, &check_nat_width, - NULL, NULL); - gtk_css_gadget_get_preferred_size (priv->indicator_gadget, - GTK_ORIENTATION_VERTICAL, - -1, - &check_min, &check_nat, - NULL, NULL); - - child = gtk_bin_get_child (GTK_BIN (widget)); - if (child && gtk_widget_get_visible (child)) - { - gint child_min, child_nat; - gint child_min_baseline = -1, child_nat_baseline = -1; - - if (for_size > -1) - for_size -= check_nat_width; - - gtk_widget_get_preferred_height_and_baseline_for_width (child, for_size, - &child_min, &child_nat, - &child_min_baseline, &child_nat_baseline); - - *minimum = MAX (check_min, child_min); - *natural = MAX (check_nat, child_nat); - - if (minimum_baseline && child_min_baseline >= 0) - *minimum_baseline = child_min_baseline + (*minimum - child_min) / 2; - if (natural_baseline && child_nat_baseline >= 0) - *natural_baseline = child_nat_baseline + (*natural - child_nat) / 2; - } - else - { - *minimum = check_min; - *natural = check_nat; - } - } -} - static void gtk_check_button_get_preferred_width_for_height (GtkWidget *widget, gint height, @@ -635,13 +494,16 @@ gtk_check_button_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget)); + GtkButton *button = GTK_BUTTON (widget); GtkCssGadget *gadget; GdkRectangle clip; + PangoContext *pango_context; + PangoFontMetrics *metrics; if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget))) gadget = priv->gadget; else - gadget = GTK_BUTTON (widget)->priv->gadget; + gadget = button->priv->gadget; gtk_widget_set_allocation (widget, allocation); gtk_css_gadget_allocate (gadget, @@ -650,71 +512,6 @@ gtk_check_button_size_allocate (GtkWidget *widget, &clip); gtk_widget_set_clip (widget, &clip); -} - -static void -gtk_check_button_allocate (GtkCssGadget *gadget, - const GtkAllocation *allocation, - int baseline, - GtkAllocation *out_clip, - gpointer unused) -{ - GtkCheckButtonPrivate *priv; - GtkWidget *widget; - PangoContext *pango_context; - PangoFontMetrics *metrics; - GtkCheckButton *check_button; - GtkButton *button; - GtkAllocation child_allocation; - GtkWidget *child; - gint check_width, check_height; - GdkRectangle check_clip; - - widget = gtk_css_gadget_get_owner (gadget); - button = GTK_BUTTON (widget); - check_button = GTK_CHECK_BUTTON (widget); - priv = gtk_check_button_get_instance_private (check_button); - - g_assert (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget))); - - gtk_css_gadget_get_preferred_size (priv->indicator_gadget, - GTK_ORIENTATION_HORIZONTAL, - -1, - NULL, &check_width, - NULL, NULL); - gtk_css_gadget_get_preferred_size (priv->indicator_gadget, - GTK_ORIENTATION_VERTICAL, - -1, - NULL, &check_height, - NULL, NULL); - - child = gtk_bin_get_child (GTK_BIN (button)); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - child_allocation.x = allocation->x; - else - child_allocation.x = allocation->x + allocation->width - check_width; - child_allocation.y = allocation->y + (allocation->height - check_height) / 2; - child_allocation.width = check_width; - child_allocation.height = check_height; - - gtk_css_gadget_allocate (priv->indicator_gadget, - &child_allocation, - baseline, - &check_clip); - - if (child && gtk_widget_get_visible (child)) - { - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - child_allocation.x = allocation->x + check_width; - else - child_allocation.x = allocation->x; - child_allocation.y = allocation->y; - child_allocation.width = allocation->width - check_width; - child_allocation.height = allocation->height; - - gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline); - } pango_context = gtk_widget_get_pango_context (widget); metrics = pango_context_get_metrics (pango_context, @@ -735,9 +532,6 @@ gtk_check_button_allocate (GtkCssGadget *gadget, border_allocation.width, border_allocation.height); } - - gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip); - gdk_rectangle_union (out_clip, &check_clip, out_clip); } static gint @@ -757,19 +551,6 @@ gtk_check_button_draw (GtkWidget *widget, return FALSE; } -static void -gtk_check_button_draw_indicator (GtkCheckButton *check_button, - cairo_t *cr) -{ - GtkCheckButtonClass *class = GTK_CHECK_BUTTON_GET_CLASS (check_button); - GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button); - - if (class->draw_indicator) - class->draw_indicator (check_button, cr); - else - gtk_css_gadget_draw (priv->indicator_gadget, cr); -} - GtkCssNode * gtk_check_button_get_indicator_node (GtkCheckButton *check_button) { -- 2.30.2